﻿// HSS.Interlink.UI.ContextMenuItem.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.html)
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2012
// ----------------------------------------------------------------------------
// File:       ContextMenuItem.cs
// Author:     HSS\gbanta
// Created:    01/17/2012
// Modified:   01/17/2012
// ----------------------------------------------------------------------------
namespace HSS.Interlink.UI
{
	#region Using Directives
	using System;
	using System.Reflection;
	using System.Windows.Input;
	using System.Windows.Media;
	#endregion

	#region ContextMenuItem
	/// <summary>
	/// A simple ContextMenuItem base class.
	/// </summary>
	public class ContextMenuItem
	{
		#region Constructors
		/// <summary>
		/// Constructor
		/// </summary>
		public ContextMenuItem()
		{
			this.Text = string.Empty;
			this.Execute = this.DefaultExecute;
			this.CanExecute = this.CanExecuteDefault;
		}
		#endregion

		#region Properties

		/// <summary>
		/// Gets or sets the Action to perform.
		/// </summary>
		public Action Execute
		{
			get;
			set;
		}
		/// <summary>
		/// Gets or sets the CanExecute Func'bool
		/// </summary>
		public Func<bool> CanExecute
		{
			get;
			set;
		}
		/// <summary>
		/// Gets or sets the DataContext this menu item is associated with.
		/// </summary>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		internal object ParentDataContext
		{
			get { return _parentDataContext; }
			set
			{
				if (_parentDataContext != value)
				{
					this.command = null;
					_parentDataContext = value;
					this.ResolveCommand(value);
				}
			}
		} object _parentDataContext;

		/// <summary>
		/// Gets or sets the Text to display for this MenuItem.
		/// </summary>
		public string Text
		{
			get;
			set;
		}
		/// <summary>
		/// Gets or sets the image for this Menu Item
		/// </summary>
		public ImageSource Image
		{
			get;
			set;
		}

		#region CommandName
		/// <summary>
		/// Gets or sets the name of the command this action should invoke.
		/// </summary>
		public string CommandName
		{
			get;
			set;
		} ICommand command = null;
		#endregion

		#endregion

		#region Overrides
		/// <summary>
		/// Returns the Text
		/// </summary>
		/// <returns>The Text</returns>
		public override string ToString()
		{
			return "[" + this.GetType().Name + "] " + this.Text;
		}
		#endregion

		#region Methods
		internal void OnClick()
		{
			if (null != this.Execute)
				this.Execute();
		}
		private bool CanExecuteDefault()
		{
			if (null != this.command)
				return this.command.CanExecute(null);
			else
				return true;
		}
		private void DefaultExecute()
		{
			if (null != this.command && this.command.CanExecute(null))
				this.command.Execute(null);
		}
		private void ResolveCommand(object dataContext)
		{
			var context = dataContext;
			if (null != context)
			{
				foreach (var info in context.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
				{
					if (typeof(ICommand).IsAssignableFrom(info.PropertyType) && string.Equals(info.Name, this.CommandName, StringComparison.Ordinal))
					{
						this.command = (ICommand)info.GetValue(context, null);
						if (null != this.command)
							return;
					}
				}
			}
		}
		#endregion
	}
	#endregion
}